package org.grapes.wine.api.server.servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.transform.Result;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.apache.log4j.Logger;
import org.grapes.wine.api.server.exception.MethodErrorCode;
import org.grapes.wine.api.server.exception.MethodException;
import org.grapes.wine.api.server.method.command.MethodCommand;
import org.grapes.wine.api.server.method.impl.factory.MethodCommandFactory;
import org.w3c.dom.Document;

/**
 * Servlet implementation class RestServer
 */
public class RestServer extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private static Logger logger = Logger.getLogger(RestServer.class);

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		this.process(req, resp);
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		this.process(req, resp);
	}

	private void process(HttpServletRequest request,
			HttpServletResponse response) {
		response.setHeader("Content-Type", "text/xml; charset=UTF-8");
		Document doc;
		try {
			MethodCommand methodCommand = MethodCommandFactory
					.newInstance(request);
			logger.info(methodCommand.getMethodName());

			doc = methodCommand.execute(request);
			if (doc == null)
				throw new MethodException(MethodErrorCode.DOCUMENT_NULL);
			renderDocument(doc, request, response);
		} catch (MethodException me) {
			doc = me.getDocument();
			try {
				renderDocument(doc, request, response);
			} catch (IOException e) {
				e.printStackTrace();
			} catch (ServletException e) {
				e.printStackTrace();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	private void renderDocument(Document doc, HttpServletRequest request,
			HttpServletResponse response) throws IOException, ServletException {
		response.setContentType("text/xml");
		try {
			TransformerFactory transformerFactory;
			transformerFactory = TransformerFactory.newInstance();
			Transformer identity = transformerFactory.newTransformer();

			Result result = new StreamResult(response.getOutputStream());
			identity.transform(new DOMSource(doc), result);
		} catch (TransformerException e) {
			throw new ServletException(
					"Unable to preform identity transformation", e);
		}
	}
}
